#include "los_task.h"
#include "ohos_init.h"
#include "iot_gpio.h"
#include "iot_errno.h"
#include "los_swtmr.h"
#include <stdio.h>

// 风扇控制引脚
#define GPIO_FAN GPIO0_PA5

// 电热丝控制引脚
#define GPIO_HEATER GPIO0_PA4

#define HEAT_PWM_INTERVAL_MS 1000 // 1秒周期，用来做一次PWM波形

// 全局变量：控制任务参数
static int g_heaterLevel = 1;   //烘干挡位
static int g_dryTimeSec = 0;   //总时间
static int g_isRunning = 0;   //运行状态

static unsigned int g_heatPwmTimerId = 0;   //烘干定时器ID
static unsigned int g_stopTimerId = 0;   //停止定时器ID

// --- PWM 配置 ---
#define PWM_TICK_MS 100       // 定时器触发间隔 (单位: 毫秒)，即 PWM Tick 长度
#define PWM_CYCLE_TICKS 10    // 一个完整 PWM 周期的 Tick 数量 (10 * 100ms = 1000ms = 1 秒)

void HeatPwmTimerHandler(UINT32 arg)
{
    // 1. 安全检查：确认系统是否处于运行状态
    //    只有在 g_isRunning == 2 (运行中) 时才执行 PWM 逻辑
    if (g_isRunning != 2) {
        // 如果不在运行状态，最好确保加热器是关闭的，防止意外状态
        IoTGpioSetOutputVal(GPIO_HEATER, IOT_GPIO_VALUE0); // 可选的安全措施
        return; // 直接退出，不执行后续 PWM 操作
    }

    // 2. 维护 PWM 周期内的 Tick 计数器
    //    使用 static 变量，使得它的值在函数调用之间得以保留
    //    它记录当前是这个 PWM 周期的第几个 Tick (从 0 开始)
    static int pwm_tick_count = 0;

    // 3. 根据当前加热档位 (g_heaterLevel)，计算本周期需要开启多少个 Tick
    //    required_on_ticks 表示在一个完整的 PWM_CYCLE_TICKS 周期内，
    //    电热丝应该处于 ON 状态的 Tick 总数。
    int required_on_ticks = 0;
    switch (g_heaterLevel) {
        case 1: // 低档位，假设占空比 30%
            // 在 PWM_CYCLE_TICKS (10) 个 Tick 中，需要开启 3 个
            required_on_ticks = 3;
            break;
        case 2: // 中档位，假设占空比 70%
            // 在 PWM_CYCLE_TICKS (10) 个 Tick 中，需要开启 7 个
            required_on_ticks = 7;
            break;
        case 3: // 高档位，占空比 100%
            // 需要一直开启，即开启所有 Ticks
            required_on_ticks = PWM_CYCLE_TICKS; // 等于 10
            break;
        default: // 无效档位或未指定，默认关闭 (占空比 0%)
            required_on_ticks = 0;
            break;
    }

    // 4. 核心逻辑：比较当前 Tick 计数 与 需要开启的 Tick 数
    //    决定当前这个 Tick 时刻，电热丝应该是 ON 还是 OFF
    if (pwm_tick_count < required_on_ticks) {
        // 如果当前 Tick 计数 小于 需要开启的总 Tick 数，
        // 说明在这个 Tick 时刻，电热丝应该处于 ON 状态。
        IoTGpioSetOutputVal(GPIO_HEATER, IOT_GPIO_VALUE1); // 设置 GPIO 为高电平 (打开)
    } else {
        // 如果当前 Tick 计数 大于或等于 需要开启的总 Tick 数，
        // 说明在这个 Tick 时刻，电热丝应该处于 OFF 状态 (或者已经完成了本周期的 ON 部分)。
        IoTGpioSetOutputVal(GPIO_HEATER, IOT_GPIO_VALUE0); // 设置 GPIO 为低电平 (关闭)
    }

    // 5. 更新 Tick 计数器，为下一次调用做准备
    //    使用取模运算 (%) 确保计数器在 0 到 (PWM_CYCLE_TICKS - 1) 之间循环
    pwm_tick_count = (pwm_tick_count + 1) % PWM_CYCLE_TICKS;

    // 6. 避免编译器产生“未使用参数”的警告
    (void)arg;
}

/**
 * 停止加热定时器：时间到了，关掉一切
 */
void StopTimerHandler(void *arg)
{
    printf("[定时器] 时间到了，关闭风扇和电热丝\n");

    // 关闭电热丝和风扇
    IoTGpioSetOutputVal(GPIO_HEATER, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(GPIO_FAN, IOT_GPIO_VALUE1);

    g_isRunning = 0;

    // 检查风扇是否真的关闭
    unsigned int fanVal = 1; // 默认设为高电平
    if (IoTGpioGetOutputVal(GPIO_FAN, &fanVal) == IOT_SUCCESS) {
        if (fanVal == IOT_GPIO_VALUE0) {
            printf("[检查] 风扇引脚已为低电平，确认关闭\n");
        } else {
            printf("[警告] 风扇引脚仍为高电平，请检查控制逻辑！\n");
        }
    } else {
        printf("[错误] 获取风扇引脚电平失败\n");
    }

    // 停止热丝PWM定时器
    if (g_heatPwmTimerId != 0) {
        LOS_SwtmrStop(g_heatPwmTimerId);
        LOS_SwtmrDelete(g_heatPwmTimerId);
        g_heatPwmTimerId = 0;
    }

    // 停止停止定时器
    if (g_stopTimerId != 0) {
        LOS_SwtmrStop(g_stopTimerId);
        LOS_SwtmrDelete(g_stopTimerId);
        g_stopTimerId = 0;
    }
}

/**
 * 烘干任务
 */
void fan_heater_task()
{
    // 初始化 GPIO
    IoTGpioInit(GPIO_FAN);
    IoTGpioSetDir(GPIO_FAN, IOT_GPIO_DIR_OUT);

    IoTGpioInit(GPIO_HEATER);
    IoTGpioSetDir(GPIO_HEATER, IOT_GPIO_DIR_OUT);

    // 创建定时器（只创建一次）
    unsigned int ret;

    // 创建 PWM 定时器 (用于加热控制)
    if (g_heatPwmTimerId == 0) {
        ret = LOS_SwtmrCreate(PWM_TICK_MS,           // <--- 使用 PWM Tick 间隔
                              LOS_SWTMR_MODE_PERIOD, // <--- 周期模式
                              HeatPwmTimerHandler,   // <--- 绑定 PWM 回调
                              &g_heatPwmTimerId,     // <--- 使用 PWM ID
                              0);                    // <--- 参数为 0
        if (ret != LOS_OK) {
            printf("错误：创建 PWM 定时器失败: 0x%x\n", ret);
            return; // 任务无法继续
        }
    }

    // 创建停止定时器 (用于总时长控制)
    if (g_stopTimerId == 0) {
        ret = LOS_SwtmrCreate(1000,                  // <--- 使用临时间隔 (1秒)
                              LOS_SWTMR_MODE_ONCE,   // <--- 单次模式
                              StopTimerHandler,      // <--- 绑定停止回调 (确保签名正确)
                              &g_stopTimerId,        // <--- 使用停止 ID
                              0);                    // <--- 参数为 0
        if (ret != LOS_OK) {
            printf("错误：创建停止定时器失败: 0x%x\n", ret);
            if (g_heatPwmTimerId != 0) {
                LOS_SwtmrDelete(g_heatPwmTimerId);
                g_heatPwmTimerId = 0;
            }
            return; // 任务无法继续
        }
    }

    printf("任务初始化完成，等待启动...\n"); // 添加日志

    while(1){
        if(g_isRunning == 1){   //运行状态
            printf("[任务] 收到启动请求 (Level: %d, Time: %ds)\n", g_heaterLevel, g_dryTimeSec); // 添加日志

            if (IoTGpioSetOutputVal(GPIO_FAN, IOT_GPIO_VALUE0) == IOT_SUCCESS) { // <--- 检查 IOT_SUCCESS
                printf("[任务] 风扇启动成功！\n");
            } else {
                printf("[任务] 错误：启动风扇失败！\n");
                g_isRunning = 0;
                return ;
            }

            // 3.2 确保电热丝初始状态为关闭 (PWM定时器会控制)
            IoTGpioSetOutputVal(GPIO_HEATER, IOT_GPIO_VALUE0);

            // 3.3 启动 PWM 定时器 (用于加热) <--- 添加此步骤
            ret = LOS_SwtmrStart(g_heatPwmTimerId);
            if (ret != LOS_OK) {
                printf("[任务] 错误：启动 PWM 定时器失败: 0x%x\n", ret);
                IoTGpioSetOutputVal(GPIO_FAN, IOT_GPIO_VALUE0); // 关闭已启动的风扇
                g_isRunning = 0;
                return ;
            } else {
                printf("[任务] PWM 定时器已启动 (Tick: %dms)\n", PWM_TICK_MS);
            }

            // 3.4 配置并启动停止定时器 <--- 添加配置步骤
            LOS_SwtmrStop(g_stopTimerId); // 先停止一次，确保状态干净
            
            // 直接使用一次性定时器，时间设置为总烘干时间
            ret = LOS_SwtmrCreate(g_dryTimeSec * 1000,  // 设置为总时长（毫秒）
                                 LOS_SWTMR_MODE_ONCE,   // 单次模式
                                 StopTimerHandler,      // 停止回调
                                 &g_stopTimerId,        // 定时器ID
                                 0);                    // 参数
            
            if (ret == LOS_OK) {
                 // 设置成功，现在启动它
                 ret = LOS_SwtmrStart(g_stopTimerId);
                 if (ret != LOS_OK) {
                     printf("[任务] 错误：启动停止定时器失败: 0x%x\n", ret);
                     LOS_SwtmrStop(g_heatPwmTimerId); // 停止已启动的 PWM 定时器
                     IoTGpioSetOutputVal(GPIO_FAN, IOT_GPIO_VALUE0); // 关闭风扇
                     g_isRunning = 0;
                     return ;
                 } else {
                     printf("[任务] 停止定时器已配置并启动 (时长: %d 秒)\n", g_dryTimeSec);
                 }
            } else {
                // 设置超时失败 (可能函数不可用或参数错误)
                printf("[任务] 错误：设置停止定时器超时失败: 0x%x (LOS_SwtmrSetTimeout?)\n", ret);
                LOS_SwtmrStop(g_heatPwmTimerId); // 停止已启动的 PWM 定时器
                IoTGpioSetOutputVal(GPIO_FAN, IOT_GPIO_VALUE0); // 关闭风扇
                g_isRunning = 0;
                return ;
            }

            // 3.5 更新运行状态 <--- 添加此步骤
            g_isRunning = 2; // 所有启动步骤成功，将状态设置为“运行中”
            printf("[任务] 所有组件启动成功，系统进入运行状态。\n");
        }

        LOS_Msleep(200);
    }
}

/**
 * 提供接口函数用于外部控制启动烘干
 */
void fan_heater_start(int level, int durationSec)
{
    if (level < 1 || level > 3 || durationSec <= 0)
    {
        printf("参数不合法\n");
        return;
    }

    g_heaterLevel = level;
    g_dryTimeSec = durationSec;
    g_isRunning = 1; // 触发主任务启动一次
}

/**
 * 应用入口函数（开机执行）
 */
void fan_heater_demo_init(int dryLevel, int dryTime)
{
    printf("Fan heater demo started\n");

    // 停止现有的定时器
    if (g_isRunning == 2) {
        printf("停止现有的烘干过程...\n");
        StopTimerHandler(NULL); // 调用停止定时器处理函数来重置状态
    }

    // 重置全局变量
    g_heaterLevel = 1;
    g_dryTimeSec = 0;
    g_isRunning = 0;

    // 创建烘干任务（只创建一次）
    static int task_created = 0;
    if (!task_created) {
        unsigned int thread_id;
        TSK_INIT_PARAM_S task = {0};
        task.pfnTaskEntry = (TSK_ENTRY_FUNC)fan_heater_task;
        task.uwStackSize = 4096;
        task.pcName = "fan_heater_task";
        task.usTaskPrio = 10;
        if (LOS_TaskCreate(&thread_id, &task) != LOS_OK)
        {
            printf("Failed to create fan_heater_task\n");
        } else {
            task_created = 1;
        }
    }

    // 启动中挡烘干，30秒
    fan_heater_start(dryLevel, dryTime);
}

// APP_FEATURE_INIT(fan_heater_demo_init);